package net.pws.oos.biz.query.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.pws.common.beanutils.BeanUtils;
import net.pws.common.persistence.IPage;
import net.pws.common.persistence.Page;
import net.pws.common.persistence.QueryRepository;
import net.pws.common.util.DateUtils;
import net.pws.oos.biz.EntityUtils;
import net.pws.oos.biz.model.Indicator;
import net.pws.oos.biz.model.IndicatorValue;
import net.pws.oos.biz.model.User;
import net.pws.oos.biz.query.IndicatorFinder;
import net.pws.oos.biz.query.parameter.IndicatorQueryParameter;
import net.pws.oos.biz.query.parameter.IndicatorValueQueryParameter;
import net.pws.oos.biz.query.parameter.OperateLogQueryParameter;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

@Service
@SuppressWarnings({ "rawtypes", "unchecked" })
public class DefaultIndicatorFinder extends AbstractFinder implements IndicatorFinder {
    
    public IndicatorValue getIndicatorValue(String id) {
        return (IndicatorValue) entityManager.findFirst("select u from IndicatorValue u left join fetch u.indicator where u.id = ?",
                                              new Object[] { id });
    }
    
    public IndicatorValue getIndicatorValueByName(String name,String boundProperties) {
    	IndicatorValue indicatorValue = null;
    	StringBuilder hql = new StringBuilder("select u from IndicatorValue u left join fetch u.indicator i where 1=1 ");
    	List<Object> params = new ArrayList<Object>();
    	
        // params.add(name);
        // params.add(code);
		if (StringUtils.isNotEmpty(name)) {
			hql.append(" and  u.name like ? ");
			params.add("%" + name + "%");
		}
		
		if (StringUtils.isNotEmpty(boundProperties)) {
			hql.append(" and  i.boundProperties = ? ");
			params.add(boundProperties);
		}
		
        return (IndicatorValue) entityManager.findFirst("select u from IndicatorValue u left join fetch u.indicator i where u.name like ?",
                                                      new Object[] { "%" + name + "%" });
    }
    
    public IndicatorValue getIndicatorValueMap(String id) {
        IndicatorValue indicatorValue = null;
        Map map = (Map) entityManager.findFirst("select new map(iv.id as id,iv.name as name,iv.description as description,iv.createDateTime as createDateTime,i.id as indicatorId,c.id as creatorId) from IndicatorValue iv left join iv.indicator i left join iv.creator c where iv.id = ?",
                                                new Object[] { id });
        if (map != null) {
            indicatorValue = new IndicatorValue();
            BeanUtils.copyProperties(indicatorValue, map);
            String indicatorId = (String) map.get("indicatorId");
            if (StringUtils.isNotEmpty(indicatorId)) {
                Indicator indicator = entityManager.find(Indicator.class, indicatorId);
                indicatorValue.setIndicator(indicator);
            }
            String creatorId = (String) map.get("creatorId");
            if (StringUtils.isNotEmpty(creatorId)) {
                User creator = entityManager.find(User.class, creatorId);
                indicatorValue.setCreator(creator);
            }
        }
        return indicatorValue;
    }
    
//    public Role getRole(String id) {
//        return entityManager.find(Role.class, id);
//    }
    
    // user
    public int countIndicatorValue(IndicatorValueQueryParameter queryParameter) {
        StringBuilder hql = new StringBuilder("select count(u.id) from IndicatorValue u left join u.indicator where  u.deleted = false ");
        List<Object> params = new ArrayList<Object>();
        buildHqlQueryRequest(queryParameter, hql, null, params);
        Number count = (Number) entityManager.findUnique(hql.toString(), params.toArray());
        return count.intValue();
        // return ((Number)
        // entityManager.findUnique("select count(u.id) from IndicatorValue u where u.sourceSystem is not null and u.deleted = false ",
        // new Object[] {})).intValue();
    }
    
    public List<IndicatorValue> getIndicatorValueList(IndicatorValueQueryParameter queryParameter,
                                  int start,
                                  int limit) {
        
        if (StringUtils.isNotEmpty(queryParameter.getName())) {
            return (List<IndicatorValue>) ((IPage) entityManager.findPage("select count(u.id) from IndicatorValue u where u.deleted = false and (u.name like ? or u.description like ?)",
                                                                "select u from IndicatorValue u where u.deleted = false  and (u.name like ? or u.description like ?)",
                                                                new Object[] { "%" + queryParameter.getName() + "%",
                                                                              "%" + queryParameter.getName() + "%" },
                                                                start,
                                                                limit)).getData();
        }
        return (List<IndicatorValue>) ((IPage) entityManager.findPage("select count(u.id) from IndicatorValue u where u.deleted = false ",
                                                            "select u from IndicatorValue u left join u.indicator where u.deleted = false ",
                                                            new HashMap(),
                                                            start,
                                                            limit)).getData();
    }
    
    public int countIndicatorValueWithRoles(IndicatorValueQueryParameter queryParameter) {
        List<Object> params = new ArrayList<Object>();
        StringBuilder sql = new StringBuilder();
        sql.append("select count(*) as recordCount from (");
        sql.append(QueryRepository.getInstance().get("sql.listIndicatorValue"));
        buildSqlQueryRequest(sql, params, queryParameter);
        sql.append(" group by iv.id) a ");
        Map map = (Map) entityManager.nativeFindFirst(sql.toString(),
                                                      params.toArray());
        return ((Number) map.get("recordCount")).intValue();
    }
    
    public List<Map> listIndicatorValueWithRoles(IndicatorValueQueryParameter queryParameter) {
        StringBuilder sql = new StringBuilder(QueryRepository.getInstance()
                                                             .get("sql.listIndicatorValue"));
        List<Object> params = new ArrayList<Object>();
        
        buildSqlQueryRequest(sql, params, queryParameter);
        sql.append(" group by iv.id order by iv.name ");
        
        Page<Map> page = (Page<Map>) entityManager.nativeFindPage(sql.toString(),
                                                                  params.toArray(),
                                                                  queryParameter.getStart(),
                                                                  queryParameter.getLimit());
        return page.getData();
    }
    
    private void buildSqlQueryRequest(StringBuilder sql,
                                      List<Object> params,
                                      IndicatorValueQueryParameter queryParameter) {
        if (StringUtils.isNotBlank(queryParameter.getName())) {
            sql.append(" and (iv.name like ? ) ");
            String like = "%" + queryParameter.getName() + "%";
            params.add(like);
        }
        if (StringUtils.isNotBlank(queryParameter.getIndicatorId())) {
            Indicator indicator = entityManager.find(Indicator.class,
                                                  queryParameter.getIndicatorId());
            if (indicator != null) {
                sql.append(" and i.inner_code like ? ");
                params.add(indicator.getInnerCode() + "%");
            }
        }
//        if (StringUtils.isNotBlank(queryParameter.getRoleId())) {
//            sql.append(" and r.id=? ");
//            params.add(queryParameter.getRoleId());
//        }
    }
    
    public List<IndicatorValue> getIndicatorValueListByIndicator(String indicatorId) {
        String hql = "from IndicatorValue u where u.indicator.id=? and u.deleted = false ";
        return entityManager.findList(hql, new Object[] { indicatorId });
    }
    
    /**
     * 根据绑定属性值（即字段名）获得指定指标项的指标值
     */
    public List<IndicatorValue> getIndicatorValueListByIndicatorProp(String boundProperties) {
    	String hql = "select new IndicatorValue(u.id,u.name) from IndicatorValue u where u.indicator.boundProperties=? and u.deleted = false order by u.id ";
    	return entityManager.findList(hql, new Object[] { boundProperties });
    }
    
    public List<IndicatorValue> getIndicatorValueListByIndicatorTree(String indicatorId) {
        Indicator indicator = entityManager.find(Indicator.class, indicatorId);
        if (indicator == null) {
            return Collections.EMPTY_LIST;
        }
        
        String likeCode = indicator.getInnerCode() + "%";
        String hql = "from IndicatorValue u where u.indicator.innerCode like ? ";
        return entityManager.findList(hql, new Object[] { likeCode });
    }
    
    public List<IndicatorValue> getIndicatorValueList(String ids) {
        if (StringUtils.isBlank(ids)) {
            return Collections.EMPTY_LIST;
        }
        StringBuilder hql = new StringBuilder("from IndicatorValue u where u.id in (");
        String[] idArray = ids.split(",");
        for (int i = 0; i < idArray.length; i++) {
            if (i > 0) {
                hql.append(",");
            }
            hql.append("'").append(idArray[i]).append("'");
        }
        hql.append(")");
        return entityManager.findList(hql.toString(), new Object[] {});
    }
    
    public List<Map> getIndicatorValueMapList(IndicatorValueQueryParameter queryParameter,
                                    int start,
                                    int limit) {
        StringBuilder hql1 = new StringBuilder("select count(u.id) from IndicatorValue u left join u.indicator where u.deleted = false ");
        StringBuilder hql2 = new StringBuilder("select new map(u.id as id,u.name as name,u.enabled as enabled,o.name as indicatorName) from IndicatorValue u left join u.indicator o where u.deleted = false ");
        List<Object> params = new ArrayList<Object>();
        buildHqlQueryRequest(queryParameter, hql1, hql2, params);
        
        return (List<Map>) ((IPage) entityManager.findPage(hql1.toString(),
                                                           hql2.toString(),
                                                           params.toArray(),
                                                           start,
                                                           limit)).getData();
        //
        // if (StringUtils.isNotEmpty(queryParameter.getName())) {
        // return (List<Map>) ((IPage)
        // entityManager.findPage("select count(u.id) from IndicatorValue u where u.sourceSystem is not null and  u.deleted = false and (u.name like ? or u.account like ?)",
        // "select new map(u.id as id,u.name as name,u.account as account,u.enabled as enabled,u.webAccessAllowed as webAccessAllowed,u.mobileAccessAllowed as mobileAccessAllowed,o.name as indicatorName) from IndicatorValue u left join u.indicator o where u.sourceSystem is not null and  u.deleted = false and (u.name like ? or u.account like ?)",
        // new Object[] { "%" + queryParameter.getName()
        // + "%",
        // "%" + queryParameter.getName()
        // + "%" },
        // start,
        // limit)).getData();
        // }
        // return (List<Map>) ((IPage)
        // entityManager.findPage("select count(u.id) from IndicatorValue u where u.sourceSystem is not null and  u.deleted = false ",
        // "select new map(u.id as id,u.name as name,u.account as account,u.enabled as enabled,u.webAccessAllowed as webAccessAllowed,u.mobileAccessAllowed as mobileAccessAllowed,o.name as indicatorName) from IndicatorValue u left join u.indicator o where u.sourceSystem is not null and  u.deleted = false ",
        // new HashMap(),
        // start,
        // limit)).getData();
    }
    
    // user
    public int countOurIndicatorValue(IndicatorValueQueryParameter queryParameter) {
        StringBuilder hql = new StringBuilder("select count(u.id) from IndicatorValue u left join u.indicator where u.deleted = false ");
        List<Object> params = new ArrayList<Object>();
        buildHqlQueryRequest(queryParameter, hql, null, params);
        Number count = (Number) entityManager.findUnique(hql.toString(),
                                                         params.toArray());
        return count.intValue();
        
        // if (StringUtils.isNotEmpty(queryParameter.getName())) {
        // return ((Number)
        // entityManager.findUnique("select count(u.id) from IndicatorValue u where  u.deleted = false and (u.name like ? or u.account like ?)",
        // new Object[] { "%" + queryParameter.getName()
        // + "%",
        // "%" + queryParameter.getName()
        // + "%" })).intValue();
        // }
        // return ((Number)
        // entityManager.findUnique("select count(u.id) from IndicatorValue u where  u.deleted = false ",
        // new Object[] {})).intValue();
    }
    
    public List<IndicatorValue> getOurIndicatorValueList(IndicatorValueQueryParameter queryParameter,
                                     int start,
                                     int limit) {
        
        if (StringUtils.isNotEmpty(queryParameter.getName())) {
            return (List<IndicatorValue>) ((IPage) entityManager.findPage("select count(u.id) from IndicatorValue u where u.deleted = false  and (u.name like ? or u.account like ?)",
                                                                "select u from IndicatorValue u where u.deleted = false and (u.name like ? or u.account like ?)",
                                                                new Object[] { "%" + queryParameter.getName()
                                                                               + "%",
                                                                              "%"     + queryParameter.getName()
                                                                                      + "%" },
                                                                start,
                                                                limit)).getData();
        }
        return (List<IndicatorValue>) ((IPage) entityManager.findPage("select count(u.id) from IndicatorValue u where u.deleted = false  ",
                                                            "select u from IndicatorValue u left join u.indicator where  u.deleted = false ",
                                                            new HashMap(),
                                                            start,
                                                            limit)).getData();
    }
    
    public List<Map> getOurIndicatorValueMapList(IndicatorValueQueryParameter queryParameter,
                                       int start,
                                       int limit) {
        StringBuilder hql1 = new StringBuilder("select count(u.id) from IndicatorValue u left join u.indicator where  u.deleted = false  ");
        StringBuilder hql2 = new StringBuilder("select new map(u.id as id,u.name as name,u.account as account,u.mobile as mobile,u.enabled as enabled,u.webAccessAllowed as webAccessAllowed,u.mobileAccessAllowed as mobileAccessAllowed,o.name as indicatorName) from IndicatorValue u left join u.indicator o where  u.deleted = false  ");
        List<Object> params = new ArrayList<Object>();
        buildHqlQueryRequest(queryParameter, hql1, hql2, params);
        
        return (List<Map>) ((IPage) entityManager.findPage(hql1.toString(),
                                                           hql2.toString(),
                                                           params.toArray(),
                                                           start,
                                                           limit)).getData();
        
        // if (StringUtils.isNotEmpty(queryParameter.getName())) {
        // return (List<Map>) ((IPage)
        // entityManager.findPage("select count(u.id) from IndicatorValue u where u.deleted = false and (u.name like ? or u.account like ?)",
        // "select new map(u.id as id,u.name as name,u.account as account,u.enabled as enabled,u.webAccessAllowed as webAccessAllowed,u.mobileAccessAllowed as mobileAccessAllowed,o.name as indicatorName) from IndicatorValue u left join u.indicator o where u.deleted = false and (u.name like ? or u.account like ?)",
        // new Object[] { "%" + queryParameter.getName()
        // + "%",
        // "%" + queryParameter.getName()
        // + "%" },
        // start,
        // limit)).getData();
        // }
        // return (List<Map>) ((IPage)
        // entityManager.findPage("select count(u.id) from IndicatorValue u where u.deleted = false ",
        // "select new map(u.id as id,u.name as name,u.account as account,u.enabled as enabled,u.webAccessAllowed as webAccessAllowed,u.mobileAccessAllowed as mobileAccessAllowed,o.name as indicatorName) from IndicatorValue u left join u.indicator o where  u.deleted = false ",
        // new HashMap(),
        // start,
        // limit)).getData();
    }
    
    private void buildHqlQueryRequest(IndicatorValueQueryParameter queryParameter,
                                      StringBuilder hql1,
                                      StringBuilder hql2,
                                      List<Object> params) {
        if (queryParameter == null) {
            return;
        }
        if (hql2 == null) {
            hql2 = new StringBuilder();
        }
        if (StringUtils.isNotEmpty(queryParameter.getName())) {
//            if (queryParameter.getName()
//                              .startsWith(IndicatorValueQueryParameter.VAGUE_ACCOUNT)) {
//                hql1.append(" and u.account like ? ");
//                hql2.append(" and u.account like ? ");
//                String like = "%" + queryParameter.getName()
//                                                  .substring(IndicatorValueQueryParameter.VAGUE_ACCOUNT.length())
//                                                  .trim()
//                              + "%";
//                params.add(like);
//            }
            if (queryParameter.getName()
                                   .startsWith(IndicatorValueQueryParameter.VAGUE_ORGAN)) {
                hql1.append(" and u.indicator.name like ? ");
                hql2.append(" and u.indicator.name like ? ");
                String like = "%" + queryParameter.getName()
                                                  .substring(IndicatorValueQueryParameter.VAGUE_ORGAN.length())
                                                  .trim()
                              + "%";
                params.add(like);
            }
            else {
                hql1.append(" and u.name like ? ");
                hql2.append(" and u.name like ? ");
                String like = "%" + queryParameter.getName() + "%";
                params.add(like);
            }
        }
        if (StringUtils.isNotEmpty(queryParameter.getIndicatorId())) {
            Indicator indicator = entityManager.find(Indicator.class,
                                                  queryParameter.getIndicatorId());
            if (indicator != null) {
                hql1.append(" and u.indicator.innerCode like ?");
                hql2.append(" and u.indicator.innerCode like ?");
                params.add(indicator.getInnerCode() + "%");
            }
        }
        if (StringUtils.isNotEmpty(queryParameter.getIndicatorValueLike())) {
            String like = "%" + queryParameter.getIndicatorValueLike() + "%";
            hql1.append(" and (u.indicator.name like ? or u.name like  ? ) ");
            hql2.append(" and (u.indicator.name like ? or u.name like  ? ) ");
            params.add(like);
            params.add(like);
        }
    }
    
//    // user bind
//    private static final String countBindedIndicatorValueSql = "select count(u.id) from s_user u where u.has_deleted = 0 and u.id in (select user_id from s_user_role ur where ur.role_id  = ?)";
//    
//    public int countBindedIndicatorValue(String roleId) {
//        return ((Number) ((Map) entityManager.nativeFindUnique(countBindedIndicatorValueSql,
//                                                               new Object[] { roleId })).values()
//                                                                                        .iterator()
//                                                                                        .next()).intValue();
//    }
    
//    private static final String getBindedIndicatorValueListSql = "select u.* from s_user u where u.has_deleted = 0 and u.id in (select user_id from s_user_role ur where ur.role_id  = ?)";
//    
//    public List<Map> getBindedIndicatorValueList(String roleId, int start, int limit) {
//        int startOfPage = Page.getStartOfPage(start, limit);
//        if (startOfPage == 0) {
//            return (List<Map>) entityManager.nativeFindList(getBindedIndicatorValueListSql + "limit ?",
//                                                            new Object[] { roleId,
//                                                                          limit });
//        }
//        else {
//            return (List<Map>) entityManager.nativeFindList(getBindedIndicatorValueListSql + "limit ?,?",
//                                                            new Object[] { roleId,
//                                                                          startOfPage,
//                                                                          startOfPage + limit });
//        }
//    }
    
//    private static String countUnbindedIndicatorValueSql = "select count(u.id) from s_user u where u.has_deleted = 0 and u.id not in (select user_id from s_user_role ur where ur.role_id = ? ) ";
//    
//    public int countUnbindedIndicatorValue(RoleQueryParameter queryParameter) {
//        if (StringUtils.isNotEmpty(queryParameter.getName())) {
//            return ((Number) ((Map) entityManager.nativeFindUnique(countUnbindedIndicatorValueSql + " and (u.name like ? or u.account like ?)",
//                                                                   new Object[] { queryParameter.getRoleId(),
//                                                                                 "%"     + queryParameter.getName()
//                                                                                         + "%",
//                                                                                 "%"     + queryParameter.getName()
//                                                                                         + "%" })).values()
//                                                                                                  .iterator()
//                                                                                                  .next()).intValue();
//        }
//        return ((Number) ((Map) entityManager.nativeFindUnique(countUnbindedIndicatorValueSql,
//                                                               new Object[] { queryParameter.getRoleId() })).values()
//                                                                                                            .iterator()
//                                                                                                            .next()).intValue();
//    }
    
//    private static String getUnbindedIndicatorValueListSql = "select u.* from s_user u where u.has_deleted = 0 and u.id not in (select user_id from s_user_role ur where ur.role_id  = ? ) ";
//    
//    public List<Map> getUnbindedIndicatorValueList(RoleQueryParameter queryParameter,
//                                         int start,
//                                         int limit) {
//        List parameter = new ArrayList();
//        parameter.add(queryParameter.getRoleId());
//        
//        StringBuffer sb = new StringBuffer(getUnbindedIndicatorValueListSql);
//        if (StringUtils.isNotEmpty(queryParameter.getName())) {
//            sb.append("and (u.name like ? or u.account like ?)");
//            parameter.add("%" + queryParameter.getName() + "%");
//            parameter.add("%" + queryParameter.getName() + "%");
//        }
//        int startOfPage = Page.getStartOfPage(start, limit);
//        if (startOfPage == 0) {
//            sb.append("limit ?");
//            parameter.add(limit);
//        }
//        else {
//            sb.append("limit ?,?");
//            parameter.add(startOfPage);
//            parameter.add(startOfPage + limit);
//        }
//        
//        return (List<Map>) entityManager.nativeFindList(sb.toString(),
//                                                        parameter.toArray());
//    }
    
//    // role bind
//    private static String countBindedRoleSql = "select count(r.id) from s_role r where r.id in (select ur.role_id from s_user_role ur where ur.user_id = ?)";
//    
//    public int countBindedRole(String userId) {
//        return ((Number) ((Map) entityManager.nativeFindUnique(countBindedRoleSql,
//                                                               new Object[] { userId })).values()
//                                                                                        .iterator()
//                                                                                        .next()).intValue();
//    }
//    
//    private static String getBindedRoleListSql = "select r.* from s_role r where r.id in (select ur.role_id from s_user_role ur where ur.user_id = ?) order by r.id ";
//    
//    public List<Map> getBindedRoleList(String userId, int start, int limit) {
//        int startOfPage = Page.getStartOfPage(start, limit);
//        if (startOfPage == 0) {
//            return (List<Map>) entityManager.nativeFindList(getBindedRoleListSql + "limit ?",
//                                                            new Object[] { userId,
//                                                                          limit });
//        }
//        else {
//            return (List<Map>) entityManager.nativeFindList(getBindedRoleListSql + "limit ?,?",
//                                                            new Object[] { userId,
//                                                                          startOfPage,
//                                                                          startOfPage + limit });
//        }
//    }
    
//    private static String countUnbindedRoleSql = "select count(r.id) from s_role r where r.id not in (select ur.role_id from s_user_role ur where ur.user_id = ?)";
//    
//    public int countUnbindedRole(IndicatorValueQueryParameter queryParameter) {
//        if (StringUtils.isNotEmpty(queryParameter.getName())) {
//            return ((Number) ((Map) entityManager.nativeFindUnique(countUnbindedRoleSql + " (r.name like ? or r.code like ?)",
//                                                                   new Object[] { queryParameter.getIndicatorValueId(),
//                                                                                 "%"     + queryParameter.getName()
//                                                                                         + "%",
//                                                                                 "%"     + queryParameter.getName()
//                                                                                         + "%" })).values()
//                                                                                                  .iterator()
//                                                                                                  .next()).intValue();
//        }
//        return ((Number) ((Map) entityManager.nativeFindUnique(countUnbindedRoleSql,
//                                                               new Object[] { queryParameter.getIndicatorValueId() })).values()
//                                                                                                            .iterator()
//                                                                                                            .next()).intValue();
//    }
    
//    private static String getUnbindedRoleListSql = "select * from s_role r where r.id not in (select ur.role_id from s_user_role ur where ur.user_id = ?)";
//    
//    public List<Map> getUnbindedRoleList(IndicatorValueQueryParameter queryParameter,
//                                         int start,
//                                         int limit) {
//        List parameter = new ArrayList();
//        parameter.add(queryParameter.getIndicatorValueId());
//        
//        StringBuffer sb = new StringBuffer(getUnbindedRoleListSql);
//        if (StringUtils.isNotEmpty(queryParameter.getName())) {
//            sb.append("and (r.name like ? or r.account like ?)");
//            parameter.add("%" + queryParameter.getName() + "%");
//            parameter.add("%" + queryParameter.getName() + "%");
//        }
//        sb.append(" order by id ");
//        
//        int startOfPage = Page.getStartOfPage(start, limit);
//        if (startOfPage == 0) {
//            sb.append("limit ?");
//            parameter.add(limit);
//        }
//        else {
//            sb.append("limit ?,?");
//            parameter.add(startOfPage);
//            parameter.add(startOfPage + limit);
//        }
//        
//        return (List<Map>) entityManager.nativeFindList(sb.toString(),
//                                                        parameter.toArray());
//    }
//    
//    // role
//    public int countRole(RoleQueryParameter queryParameter) {
//        if (StringUtils.isNotEmpty(queryParameter.getName())) {
//            return ((Number) entityManager.findUnique("select count(u.id) from Role u where u.name like ? or u.code like ?",
//                                                      new Object[] { "%" + queryParameter.getName()
//                                                                     + "%",
//                                                                    "%"     + queryParameter.getName()
//                                                                            + "%" })).intValue();
//        }
//        
//        return ((Number) entityManager.findUnique("select count(r.id) from Role r",
//                                                  new HashMap())).intValue();
//    }
//    
//    public List<Role> getRoleList(RoleQueryParameter queryParameter,
//                                  int start,
//                                  int limit) {
//        if (StringUtils.isNotEmpty(queryParameter.getName())) {
//            return (List<Role>) ((IPage) entityManager.findPage("select count(r.id) from Role r where r.name like ? or r.code like ?",
//                                                                "select r from Role r where r.name like ? or r.code like ? order by id ",
//                                                                new Object[] { "%" + queryParameter.getName()
//                                                                               + "%",
//                                                                              "%"     + queryParameter.getName()
//                                                                                      + "%" },
//                                                                start,
//                                                                limit)).getData();
//        }
//        
//        return (List<Role>) ((IPage) entityManager.findPage("select count(r.id) from Role r",
//                                                            "from Role r order by id",
//                                                            new Object[] {},
//                                                            0,
//                                                            20)).getData();
//    }
    
    // indicator
    public int countIndicator(IndicatorQueryParameter queryParameter) {
        if (StringUtils.isNotEmpty(queryParameter.getName())) {
            return ((Number) entityManager.findUnique("select count(o.id) from Indicator o where o.deleted = false and (o.name like ? or o.shortName like ?)",
                                                      new Object[] { "%" + queryParameter.getName() + "%",
                                                                    "%" + queryParameter.getName() + "%" })).intValue();
        }
        
        return ((Number) entityManager.findUnique("select count(o.id) from Indicator o where o.deleted = false ",
                                                  new HashMap())).intValue();
    }
    
    public List<Indicator> getIndicatorList(IndicatorQueryParameter queryParameter,
                                                  int start,
                                                  int limit) {
        if (StringUtils.isNotEmpty(queryParameter.getName())) {
            return (List<Indicator>) ((IPage) entityManager.findPage("select count(o.id) from Indicator o where o.deleted = false and ( o.name like ? or o.shortName like ?)",
                                                                        "select o from Indicator o where o.deleted = false and (o.name like ? or o.shortName like ?)  order by o.depth,o.name",
                                                                        new Object[] { "%" + queryParameter.getName() + "%",
                                                                                      "%" + queryParameter.getName() + "%" },
                                                                        start,
                                                                        limit)).getData();
        }
        
        return (List<Indicator>) ((IPage) entityManager.findPage("select count(o.id) from Indicator o where o.deleted = false ",
                                                                    "select o.name from Indicator o left join o.parent where o.deleted = false order by o.depth,o.name",
                                                                    new Object[] {},
                                                                    start,
                                                                    limit)).getData();
    }
    
    public List<Map> getIndicatorMapList(IndicatorQueryParameter queryParameter,
                                            int start,
                                            int limit) {
        if (StringUtils.isNotEmpty(queryParameter.getName())) {
            return (List<Map>) ((IPage) entityManager.findPage("select count(o.id) from Indicator o where o.deleted = false and ( o.name like ? or o.shortName like ?)",
                                                               "select new map(o.id as id,o.name as name,o.shortName as shortName,o.code as code,p.name as parentName,p.innerCode as parentInnerCode) from Indicator o left join o.parent p where o.deleted = false and (o.name like ? or o.shortName like ?)  order by o.depth,o.name",
                                                               new Object[] { "%" + queryParameter.getName() + "%",
                                                                             "%" + queryParameter.getName() + "%" },
                                                               start,
                                                               limit)).getData();
        }
        
        return (List<Map>) ((IPage) entityManager.findPage("select count(o.id) from Indicator o where o.deleted = false ",
                                                           "select new map(o.id as id,o.name as name,o.shortName as shortName,o.code as code,p.name as parentName,p.innerCode as parentInnerCode) from Indicator o left join o.parent p where o.deleted = false order by o.depth,o.name",
                                                           new Object[] {},
                                                           start,
                                                           limit)).getData();
    }
    
    public List<Indicator> getIndicatorChildren(String id) {
        if (StringUtils.isEmpty(id)) {
            return (List<Indicator>) entityManager.findList("from Indicator o where o.deleted = false and o.depth = 0 order by o.sortNum",
                                                               new Object[] {});
        }
        return (List<Indicator>) entityManager.findList("from Indicator o where o.deleted = false and o.parent.id = ? order by o.depth,o.sortNum",
                                                           new Object[] { id });
    }
    
    public List<Indicator> getIndicatorChildren(String id, String excludeId) {
        if (StringUtils.isEmpty(id)) {
            return (List<Indicator>) entityManager.findList("from Indicator o where o.deleted = false and o.depth = 0 and o.id !=? order by o.sortNum",
                                                               new Object[] { excludeId });
        }
        return (List<Indicator>) entityManager.findList("from Indicator o where o.deleted = false and o.parent.id = ? and o.id !=? and o.parent.id !=? order by o.depth,o.sortNum",
                                                           new Object[] { id, excludeId, excludeId });
    }
    
    private static String countIndicatorHql = "select count(o.id) from Indicator o where o.deleted = false ";
    
    private static String listIndicatorHql = "select o from Indicator o where o.deleted = false ";
    
    private static String listIndicatorMapHql = "select new map(o.id as id,o.name as name,o.shortName as shortName,o.code as code,o.depth as depth,o.sortNum as sortNum,o.measureUnit as measureUnit,o.createDateTime as createDateTime,p.name as parentName,p.innerCode as parentInnerCode,c.name as creatorName) from Indicator o left join o.parent p left join o.creator c where o.deleted = false ";
    
    private void buildIndicatorQueryRequest(IndicatorQueryParameter queryParameter,
                                        StringBuilder hql1,
                                        StringBuilder hql2,
                                        List<Object> params) {
        if (queryParameter == null || params == null) {
            return;
        }
        if (hql2 == null) {
            hql2 = new StringBuilder();
        }
        
        if (StringUtils.isNotEmpty(queryParameter.getName())) {
            hql1.append(" and (o.name like ? or o.shortName like ?) ");
            hql2.append(" and (o.name like ? or o.shortName like ?) ");
            params.add("%" + queryParameter.getName() + "%");
            params.add("%" + queryParameter.getName() + "%");
        }
        
        if (StringUtils.isNotEmpty(queryParameter.getAncestorId())) {
            Indicator indicator = entityManager.find(Indicator.class,
                                                  queryParameter.getAncestorId());
            if (indicator != null) {
                hql1.append(" and o.innerCode like ?");
                hql2.append(" and o.innerCode like ?");
                params.add(indicator.getInnerCode() + "%");
            }
        }
    }
    
    public int countOurIndicator(IndicatorQueryParameter queryParameter) {
        StringBuilder hql = new StringBuilder(countIndicatorHql);
        List<Object> params = new ArrayList<Object>();
        buildIndicatorQueryRequest(queryParameter, hql, null, params);
        
        Number count = (Number) entityManager.findUnique(hql.toString(),
                                                         params.toArray());
        return count.intValue();
    }
    
    public List<Indicator> getOurIndicatorList(IndicatorQueryParameter queryParameter,
                                                     int start,
                                                     int limit) {
        StringBuilder hql = new StringBuilder(listIndicatorHql);
        StringBuilder hql4Count = new StringBuilder(countIndicatorHql);
        List<Object> params = new ArrayList<Object>();
        buildIndicatorQueryRequest(queryParameter, hql, hql4Count, params);
        hql.append(" order by o.depth,o.name ");
        
        IPage page = entityManager.findPage(hql4Count.toString(),
                                            hql.toString(),
                                            params.toArray(),
                                            start,
                                            limit);
        return page.getData();
    }
    
    public List<Map> getOurIndicatorMapList(IndicatorQueryParameter queryParameter,
                                               int start,
                                               int limit) {
        StringBuilder hql = new StringBuilder(listIndicatorMapHql);
        StringBuilder hql4Count = new StringBuilder(countIndicatorHql);
        List<Object> params = new ArrayList<Object>();
        buildIndicatorQueryRequest(queryParameter, hql, hql4Count, params);
        hql.append(" order by o.depth,o.sortNum,o.name ");
        
        IPage page = entityManager.findPage(hql4Count.toString(),
                                            hql.toString(),
                                            params.toArray(),
                                            start,
                                            limit);
        return page.getData();
    }
    
    public Indicator getIndicator(String id) {
        return (Indicator) entityManager.findFirst("select o from Indicator o left join o.parent where o.deleted = false and o.id = ?",
                                                      new Object[] { id });
    }
    
    public Indicator getIndicatorMap(String id) {
        Indicator indicator = null;
        Map map = (Map) entityManager.findFirst("select new map(o.id as id,o.name as name,o.shortName as shortName,o.code as code,p.id as parentId,o.description as description,o.deleted as deleted,o.depth as depth,o.createDateTime as createDateTime,o.deleteDateTime as deleteDateTime,o.boundProperties as boundProperties,c.id as creatorId,o.inputType as inputType,o.sortNum as sortNum) from Indicator o left join o.parent p left join o.creator c where o.deleted = false and o.id = ?",
                                                new Object[] { id });
        if (map != null) {
            indicator = new Indicator();
            BeanUtils.copyProperties(indicator, map);
            String parentId = (String) map.get("parentId");
            if (StringUtils.isNotEmpty(parentId)) {
                Indicator parent = entityManager.find(Indicator.class, parentId);
                indicator.setParent(parent);
            }
            String creatorId = (String) map.get("creatorId");
            if (StringUtils.isNotEmpty(creatorId)) {
            	User creator = entityManager.find(User.class, creatorId);
                indicator.setCreator(creator);
            }

        }
        
        return indicator;
    }
    
    @Override
    public Indicator getDepthIndicator(String id, int depth) {
        Indicator source = entityManager.find(Indicator.class, id);
        if (source == null) {
            return null;
        }
        
        if (source.getDepth() < depth) {
            return null;
        }
        
        if (source.getDepth() == depth) {
            return source;
        }
        
        String innerCode = EntityUtils.getValidInnerCode(source.getInnerCode(),
                                                         depth);
        return getIndicatorByInnerCode(innerCode);
    }
    
    private Indicator getIndicatorByInnerCode(String innerCode) {
        return (Indicator) entityManager.findFirst("select o from Indicator o where o.innerCode = ?",
                                                      new Object[] { innerCode });
    }
    
    public int countOperateLog(OperateLogQueryParameter queryParameter) {
        StringBuilder hql = new StringBuilder(QueryRepository.getInstance()
                                                             .get("hql.getOperateLogCount"));
        List<Object> params = new ArrayList<Object>();
        buildOperateLogQuery(hql, null, params, queryParameter);
        Number count = (Number) entityManager.findFirst(hql.toString(),
                                                        params.toArray());
        return count.intValue();
    }
    
    public List<Map> listOperateLog(OperateLogQueryParameter queryParameter) {
        StringBuilder countHql = new StringBuilder(QueryRepository.getInstance()
                                                                  .get("hql.getOperateLogCount"));
        StringBuilder hql = new StringBuilder(QueryRepository.getInstance()
                                                             .get("hql.getOperateLogList"));
        List<Object> params = new ArrayList<Object>();
        buildOperateLogQuery(hql, countHql, params, queryParameter);
        
        hql.append(" order by l.operateDate desc ");
        Page<Map> page = (Page<Map>) entityManager.findPage(countHql.toString(),
                                                            hql.toString(),
                                                            params.toArray(),
                                                            queryParameter.getStart(),
                                                            queryParameter.getLimit());
        return page.getData();
    }
    
    private void buildOperateLogQuery(StringBuilder sql,
                                      StringBuilder sql2,
                                      List<Object> params,
                                      OperateLogQueryParameter queryParameter) {
        if (sql == null || params == null || queryParameter == null) {
            return;
        }
        if (sql2 == null) {
            sql2 = new StringBuilder();
        }
        
//        if (StringUtils.isNotBlank(queryParameter.getIndicatorValueId())) {
//            sql.append(" and l.user.id=? ");
//            sql2.append(" and l.user.id=? ");
//            params.add(queryParameter.getIndicatorValueId());
//        }
//        
//        if (StringUtils.isNotBlank(queryParameter.getIndicatorId())) {
//            Indicator indicator = entityManager.find(Indicator.class,
//                                                  queryParameter.getIndicatorId());
//            if (indicator != null) {
//                sql.append(" and o.innerCode like ?");
//                sql2.append(" and o.innerCode like ?");
//                params.add(indicator.getInnerCode() + "%");
//            }
//        }
        
        if (StringUtils.isNotBlank(queryParameter.getType())) {
            sql.append(" and l.type=? ");
            sql2.append(" and l.type=? ");
            params.add(queryParameter.getType());
        }
        
        if (StringUtils.isNotBlank(queryParameter.getClient())) {
            sql.append(" and l.client=? ");
            sql2.append(" and l.client=? ");
            params.add(queryParameter.getClient());
        }
        
        if (StringUtils.isNotBlank(queryParameter.getUri())) {
            sql.append(" and l.uri like ? ");
            sql2.append(" and l.uri like ? ");
            params.add("%" + queryParameter.getUri() + "%");
        }
        
        if (StringUtils.isNotBlank(queryParameter.getIp())) {
            sql.append(" and l.ip like ? ");
            sql2.append(" and l.ip like ? ");
            params.add("%" + queryParameter.getIp() + "%");
        }
        
        // 操作时间
        if (queryParameter.getStartDate() != null) {
            sql.append(" and l.operateDate>=? ");
            sql2.append(" and l.operateDate>=? ");
            params.add(queryParameter.getStartDate());
        }
        if (queryParameter.getEndDate() != null) {
            sql.append(" and l.operateDate<? ");
            sql2.append(" and l.operateDate<? ");
            params.add(DateUtils.addDay(queryParameter.getEndDate(), 1));
        }
    }
    
    public List<Indicator> getIndicatorByDepth(int depth) {
    	return (List<Indicator>) entityManager.findList("from Indicator o where o.deleted = false and o.depth = ? order by o.sortNum",
                                                           new Object[] {depth});
    }
        
}
